#include "XThread.h"
#include <thread>
#include <iostream>
#include <event2/event.h>
#include "XTask.h"
#include <unistd.h>

using namespace std;

/**
 * @fn
 * @brief 激活线程任务的回调函数
 * @param[in]
 * @param[out]
 * @retval
 */
void XThread::NotifyCB(evutil_socket_t fd, short which, void *arg)
{
    XThread *t = (XThread *)arg;
    t->Notify(fd, which);
}

/**
 * @fn
 * @brief 读取管道
 * @param[in]
 * @param[out]
 * @retval
 */

void XThread::Notify(evutil_socket_t fd, short which)
{
    //水平触发 只要没有接受完成，会再次进来
    char buf[2] = {0};

    /* 读取管道 */
    int ret = read(fd, buf, 1);

    if (ret <= 0)
    {
        return;
    }
    cout << " thread id:" << getId()<<" read "<< buf << endl;

    /* 获取任务，并初始化任务 */
    m_mutex.lock();
    if (m_taskList.empty())
    {
        m_mutex.unlock();
        return;
    }
    XTask *task = m_taskList.front(); //先进先出
    m_taskList.pop_front();
    m_mutex.unlock();

    task->Init();
}

void XThread::AddTask(XTask *t)
{
    if (!t)
    {
        return;
    }

    t->setBase(this->m_base);

    m_mutex.lock();
    m_taskList.push_back(t);
    m_mutex.unlock();
}

//线程激活
void XThread::Activate()
{
    /* 向管道写入一个字符，用于通知线程有任务等待执行 */
    int re = write(this->m_pipeWriteFd, "c", 1);
    if (re <= 0)
    {
        cerr << "XThread::Activate() failed!" << endl;
    }
}

/**
 * @fn
 * @brief 启动线程
 * @param[in]
 * @param[out]
 * @retval
 */
void XThread::Start()
{
    Setup();
    //启动线程
    thread th(&XThread::run,this);

    //断开与主线程联系
    th.detach();
}

/**
 * @fn
 * @brief 安装线程，初始化event_base和管道监听事件用于激活
 * @param[in]
 * @param[out]
 * @retval
 */
bool XThread::Setup()
{
    int fds[2] = {0};

    /* 创建的管道 */
    if (pipe(fds))
    {
        cerr << "pipe failed!" << endl;
        return false;
    }

    /* 读取绑定到event事件中，写入要保存 */
    m_pipeWriteFd = fds[1];

    /* 创建libevent上下文（无锁）*/
    event_config *ev_conf = event_config_new();
    event_config_set_flag(ev_conf, EVENT_BASE_FLAG_NOLOCK);
    this->m_base = event_base_new_with_config(ev_conf);
    event_config_free(ev_conf);

    if (!m_base)
    {
        cerr << "event_base_new_with_config failed in thread!" << endl;
        return false;
    }

    //添加管道监听事件，用于激活线程执行任务
    event *ev = event_new(m_base, fds[0], EV_READ | EV_PERSIST, NotifyCB, this);
    event_add(ev, 0);

    return true;
}

//线程入口函数
void XThread::run()
{
    cout << " XThread::Main() begin, id=" << getId()<< endl;

    event_base_dispatch(m_base);
    event_base_free(m_base);

    cout << " XThread::Main() end, id=" << getId()<< endl;
}

int XThread::getId()
{
    return m_Id;
}

bool XThread::setId(int id)
{
    m_Id = id;
    return true;
}

XThread::XThread()
{

}

XThread::~XThread()
{
}
